package com.lgl.allpeoplevent.ventIndex.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lgl.scsapi.base.dao.DaoSupport;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.util.utils.Tools;
import com.lgl.scsapi.vent.model.Vent;
import com.lgl.scsapi.vent.model.VentUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 吐槽service
 */
@Slf4j
@Service
public class VentService {
    @Autowired
    private DaoSupport dao;

    /**
     * 保存吐槽
     * @param vent 要保存的吐槽对象
     * @return 影响的行数
     */
    public int saveVent(Vent vent) {
        return dao.save("VentMapper.saveVent", vent);
    }

    /**
     * 吐槽点赞总数+1
     * @param ventId 吐槽ID
     * @return 成功的行数
     */
    @Async
    public Integer likeTotalAddOne(Long ventId){
        return dao.update("VentMapper.likeTotalAddOne", ventId);
    }
    /**
     * 吐槽点赞总数+1
     * @param ventId 吐槽ID
     * @return 成功的行数
     */
    @Async
    public Integer commentTotalAddOne(String ventId){
        return dao.update("VentMapper.commentTotalAddOne", ventId);
    }
    /**
     * 获取吐槽信息列表(前台页面使用)
     * @param pageNo 当前页号
     * @param pageSize  每页显示记录数
     * @param pageData  PageData参数
     * @return PageInfo对象
     */
    public PageInfo pageIndexVent(int pageNo, int pageSize, PageData pageData) {
        if (paramIsNotRight(pageData)){
            return new PageInfo(new ArrayList(1));
        }
        String occupationId = pageData.getString("occupationId"), orderBy = pageData.getString("occupationId");
        //如果前端页面传过来的occupationId是数字，则说明选择是吐槽人职业类型，则默认按创建日期排序
        if (Tools.strIsInt(occupationId) || "new".equals(occupationId)){
            pageData.put("orderBy", "create_date");
            if ("new".equals(occupationId)){
                pageData.remove("occupationId");
            }
        }else {
            //如果前端页面传过来的occupationId不是数字，则说明选择是“热门”或“最新”，则按点赞量、阅读量等来排序
            pageData.put("orderBy", "like_total desc, read_total");
            pageData.remove("occupationId");
        }
        PageHelper.startPage(pageNo,pageSize);
        List<Vent> ventList = (List<Vent>) dao.findForList("VentMapper.pageVent", pageData);
        return new PageInfo(ventList);
    }
    /**
     * 获取我的吐槽信息列表(后台页面使用)
     * @param pageNo 当前页号
     * @param pageSize  每页显示记录数
     * @param pageData  PageData参数
     * @return PageInfo对象
     */
    public PageInfo pageMyVent(int pageNo, int pageSize, PageData pageData) {
        PageHelper.startPage(pageNo,pageSize);
        List<Vent> ventList = (List<Vent>) dao.findForList("VentMapper.pageMyVent", pageData);
        return new PageInfo(ventList);
    }

    /**
     * 获取推荐更多吐槽数据
     * @param pageNo 当前页号
     * @param pageSize  每页显示记录数
     * @param pageData  PageData参数
     * @return PageInfo对象
     */
    public PageInfo pageRecommendMoreVent(int pageNo, int pageSize, PageData pageData) {
        PageHelper.startPage(pageNo,pageSize);
        List<Vent> moreVentList = (List<Vent>) dao.findForList("VentMapper.pageRecommendMoreVent", pageData);
        return new PageInfo(moreVentList);
    }

    /**
     * 获取点赞量、阅读量、评论量最多的关注（根据吐槽对象、吐槽职业、吐槽人来进行猜测）的吐槽数据
     * @param pageData 查询参数和分页数据
     * @return 吐槽数据集合
     */
    public List<PageData> listFollowVentByMost(PageData pageData) {
        return (List<PageData>) dao.findForList("VentMapper.listFollowVentByMost", pageData);
    }

    /**
     * 获取点赞量、阅读量、评论量最多的的吐槽数据
     * @param pageData 查询参数和分页数据
     * @return 吐槽数据集合
     */
    public List<PageData> listMostLikeReadComment(PageData pageData) {
        return (List<PageData>) dao.findForList("VentMapper.listMostLikeReadComment", pageData);
    }
    /**
     * 获取一条吐槽数据
     * @param ventUser 当前登录用户
     * @param getVentPd 查询参数
     * @return Vent对象
     */
    public Vent getIndexVent(VentUser ventUser,PageData getVentPd) {
        Vent vent = (Vent)dao.findForObject("VentMapper.getVent", getVentPd);
        if (vent == null){
            return null;
        }
        int ventStatus = vent.getStatus();
        String loginUserId = ventUser == null ? null : ventUser.getUserId();
        //如果状态是注销/删除 或 状态仅自己可见且吐槽的发布人不是当前登录人，则返回空
        if (ventStatus == 2 || (ventStatus == 1 && !vent.getUserId().equals(loginUserId))){
            vent = null;
        }
        return vent;
    }

    /**
     * 防止用户恶意构造参数，导致A用户或未登录用户可以查看到B用户的仅自己可见或被注销的吐槽数据，
     * 满足以下2种情况时，数据返回空：
     * 1、状态为空或为1（仅自己可见）时，且userId为空；
     * 2、状态为2时不可以查询到数据。
     * @param pageData 参数是否正常
     * @return true:不正常，false:正常
     */
    private boolean paramIsNotRight(PageData pageData){
        String ventStatus = pageData.getString("ventStatus"),
                ventUserId = pageData.getString("ventUserId");
        return (StringUtils.isEmpty(ventStatus) || "1".equals(ventStatus)
                && StringUtils.isEmpty(ventUserId)) || "2".equals(ventStatus);
    }
    /**
     * 获取点赞量、阅读量、评论量最多的的吐槽数据
     * @param pageData 查询参数和分页数据
     * @return 吐槽数据集合
     */
    public List<PageData> countVentTotalByUser(PageData pageData) {
        return (List<PageData>) dao.findForList("VentMapper.countVentTotalByUser", pageData);
    }

    /**
     * 删除吐槽数据
     * @param delPd 删除ID和当前登录用户ID
     * @return 返回行数
     */
    @Async
    @Transactional(value = "ventTxManager",propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,rollbackFor = Exception.class)
    public void delVentById(PageData delPd) throws Exception {
        //保存到删除表
        int rows = dao.save("VentMapper.saveDelVent", delPd);
        if (rows > 0){
            //从吐槽表中删除
            rows = dao.delete("VentMapper.delVentById", delPd);
        }
        if (rows < 1){
            throw new Exception("删除吐槽对象失败");
        }
    }

    /**
     * 吐槽阅读量加1
     * @param ventId 吐槽ID
     */
    public void readTotalAddOne(String ventId) {
        int r = dao.update("VentMapper.readTotalAddOne", ventId);
        if (r < 1){
            log.error("吐槽数据id=[" + ventId + "]阅读量加1失败");
        }
    }

    /**
     * 通过关键字搜索吐槽对象集合
     * @param ventPd 关键字
     * @return 吐槽对象集合
     */
    public List<PageData> listVentToName(PageData ventPd) {
        if (ventPd == null || ventPd.isEmpty()){
            return null;
        }
        return (List<PageData>) dao.findForList("VentMapper.listVentToName", ventPd);
    }
}